using System;
using System.Data;
using System.Collections.Generic;
using System.Text;

namespace Common.Utilities
{
    /// <summary>
    /// 
    /// </summary>
    [Serializable]
    public class Tuple : IComparable, ICloneable 
    {
        private string _Name;
        /// <summary></summary>
        public string Name
        {
            get { return _Name; }
            set { _Name = value; }
        }
        private System.Data.SqlDbType _DbType;
        /// <summary></summary>
        public System.Data.SqlDbType DbType
        {
            get { return _DbType; }
            set { _DbType = value; }
        }
        private string _Value;
        /// <summary></summary>
        public string Value
        {
            get { return _Value; }
            set { _Value = value; }
        }
        /// <summary></summary>
        public bool IsQuoteType
        {
            get
            {
                bool needQuote = false;
                switch (this._DbType)
                {
                    case System.Data.SqlDbType.BigInt:
                    case System.Data.SqlDbType.Decimal:
                    case System.Data.SqlDbType.Float:
                    case System.Data.SqlDbType.Int:
                    case System.Data.SqlDbType.Money:
                    case System.Data.SqlDbType.Real:
                    case System.Data.SqlDbType.SmallInt:
                    case System.Data.SqlDbType.SmallMoney:
                    case System.Data.SqlDbType.TinyInt:
                        needQuote = false;
                        break;
                    case SqlDbType.Char:
                    case SqlDbType.VarChar:
                    case SqlDbType.NChar:
                    case SqlDbType.NVarChar:
                        needQuote = true;
                        break;
                    case SqlDbType.NText:
                    case SqlDbType.Text:
                        needQuote = true;
                        break;
                    case SqlDbType.Bit:
                        needQuote = false;
                        break;
                    case SqlDbType.DateTime:
                    case SqlDbType.SmallDateTime:
                        needQuote = true;
                        break;
                    case SqlDbType.Binary:
                    case SqlDbType.Image:
                    case SqlDbType.VarBinary:
                        needQuote = false;
                        break;
                    default:
                        break;
                }
                return needQuote;
            }
        }

        #region IComparable Members

        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public int CompareTo(object obj)
        {
            if (obj.GetType() == typeof(Tuple))
            {
                Tuple otherTuple = (Tuple)obj;
                if (Tuple.IsNumberDataType(this._DbType) && Tuple.IsNumberDataType(otherTuple.DbType))
                {
                    decimal thisVal = decimal.Parse(this.Value);
                    decimal otherVal = decimal.Parse(otherTuple.Value);
                    return thisVal.CompareTo(otherVal);
                }
                else if (Tuple.IsDateTimeDataType(this.DbType) && Tuple.IsDateTimeDataType(otherTuple.DbType))
                {
                    DateTime thisVal = DateTime.Parse(this.Value);
                    DateTime otherVal = DateTime.Parse(otherTuple.Value);
                    return thisVal.CompareTo(otherVal);
                }
                else if (Tuple.IsBooleanDataType(this.DbType) && Tuple.IsBooleanDataType(otherTuple.DbType))
                {
                    bool thisVal = bool.Parse(this.Value);
                    bool otherVal = bool.Parse(otherTuple.Value);
                    return thisVal.CompareTo(otherVal);
                }
                else
                {
                    return this.Value.CompareTo(otherTuple.Value);
                }
            }
            else
            {
                return 0;
            }
        }

        #endregion

        #region static methods
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbType"></param>
        /// <returns></returns>
        public static bool IsNumberDataType(System.Data.SqlDbType dbType)
        {
            bool result = false;
            switch (dbType)
            {
                case System.Data.SqlDbType.BigInt:
                case System.Data.SqlDbType.Decimal:
                case System.Data.SqlDbType.Float:
                case System.Data.SqlDbType.Int:
                case System.Data.SqlDbType.Money:
                case System.Data.SqlDbType.Real:
                case System.Data.SqlDbType.SmallInt:
                case System.Data.SqlDbType.SmallMoney:
                case System.Data.SqlDbType.TinyInt:
                    result = true;
                    break;
                case SqlDbType.Char:
                case SqlDbType.NChar:
                case SqlDbType.NText:
                case SqlDbType.NVarChar:
                case SqlDbType.Text:
                case SqlDbType.VarChar:
                    result = false;
                    break;
                case SqlDbType.Bit:
                    result = false;
                    break;
                case SqlDbType.DateTime:
                case SqlDbType.SmallDateTime:
                    result = false;
                    break;
            }
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbType"></param>
        /// <returns></returns>
        public static bool IsStringDataType(System.Data.SqlDbType dbType)
        {
            bool result = false;
            switch (dbType)
            {
                case System.Data.SqlDbType.BigInt:
                case System.Data.SqlDbType.Decimal:
                case System.Data.SqlDbType.Float:
                case System.Data.SqlDbType.Int:
                case System.Data.SqlDbType.Money:
                case System.Data.SqlDbType.Real:
                case System.Data.SqlDbType.SmallInt:
                case System.Data.SqlDbType.SmallMoney:
                case System.Data.SqlDbType.TinyInt:
                    result = false;
                    break;
                case SqlDbType.Char:
                case SqlDbType.NChar:
                case SqlDbType.NText:
                case SqlDbType.NVarChar:
                case SqlDbType.Text:
                case SqlDbType.VarChar:
                    result = true;
                    break;
                case SqlDbType.Bit:
                    result = false;
                    break;
                case SqlDbType.DateTime:
                case SqlDbType.SmallDateTime:
                    result = false;
                    break;
            }
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbType"></param>
        /// <returns></returns>
        public static bool IsBooleanDataType(System.Data.SqlDbType dbType)
        {
            bool result = false;
            switch (dbType)
            {
                case System.Data.SqlDbType.BigInt:
                case System.Data.SqlDbType.Decimal:
                case System.Data.SqlDbType.Float:
                case System.Data.SqlDbType.Int:
                case System.Data.SqlDbType.Money:
                case System.Data.SqlDbType.Real:
                case System.Data.SqlDbType.SmallInt:
                case System.Data.SqlDbType.SmallMoney:
                case System.Data.SqlDbType.TinyInt:
                    result = false;
                    break;
                case SqlDbType.Char:
                case SqlDbType.NChar:
                case SqlDbType.NText:
                case SqlDbType.NVarChar:
                case SqlDbType.Text:
                case SqlDbType.VarChar:
                    result = false;
                    break;
                case SqlDbType.Bit:
                    result = true;
                    break;
                case SqlDbType.DateTime:
                case SqlDbType.SmallDateTime:
                    result = false;
                    break;
            }
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbType"></param>
        /// <returns></returns>
        public static bool IsDateTimeDataType(System.Data.SqlDbType dbType)
        {
            bool result = false;
            switch (dbType)
            {
                case System.Data.SqlDbType.BigInt:
                case System.Data.SqlDbType.Decimal:
                case System.Data.SqlDbType.Float:
                case System.Data.SqlDbType.Int:
                case System.Data.SqlDbType.Money:
                case System.Data.SqlDbType.Real:
                case System.Data.SqlDbType.SmallInt:
                case System.Data.SqlDbType.SmallMoney:
                case System.Data.SqlDbType.TinyInt:
                    result = false;
                    break;
                case SqlDbType.Char:
                case SqlDbType.NChar:
                case SqlDbType.NText:
                case SqlDbType.NVarChar:
                case SqlDbType.Text:
                case SqlDbType.VarChar:
                    result = false;
                    break;
                case SqlDbType.Bit:
                    result = false;
                    break;
                case SqlDbType.DateTime:
                case SqlDbType.SmallDateTime:
                    result = true;
                    break;
            }
            return result;
        }
        #endregion

        #region ICloneable Members

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            Tuple clone = new Tuple();
            clone.DbType = this._DbType;
            clone.Name = this._Name;
            clone.Value = this._Value;
            return clone;
        }

        #endregion
    }
}
